﻿Imports knfUpdateDataLayer


Public Class Indicatore

    Private nIndice As Integer
    Public Property Indice() As String
        Get
            Return nIndice
        End Get
        Set(ByVal value As String)
            nIndice = value
        End Set
    End Property

    Private nValue As Decimal
    Public Property Value() As Decimal
        Get
            Return nValue
        End Get
        Set(ByVal value As Decimal)
            nValue = value
        End Set
    End Property

End Class


Public Class CalcoloReporter

    Private _db As knfEntities

    Private nAnno As Integer
    Private nReporter As String
    Private nReportType As String
    Private nAliasProduct As String
    Private nHashData As New Hashtable
    Private nHashDataInvertito As New Hashtable
    Private nlistaPartner As New List(Of String)
    Private nlistaPartnerInvertito As New List(Of String)



    Private nFlux As String
    Private nRawDataReporter As New List(Of RawData)
    Private nRawDataPartner As New List(Of RawData)




    Public Sub New(ByVal anno As Integer, ByVal reporter As String)
        nAnno = anno
        nReporter = reporter
        _db = New knfEntities()
    End Sub


#Region "funzioni private"

    Private Function TrovaIndice(ByVal country As String, ByVal listaInput As List(Of String))
        Dim indicescelto As Integer = 0
        Dim contatore As Integer = 0

        For Each inputString As String In listaInput
            If inputString = country Then
                indicescelto = contatore
                Exit For
            End If
            contatore += 1
        Next

        Return indicescelto

    End Function

    Private Function CreaHash(ByVal listaReporter As List(Of RawData)) As Hashtable

        Dim gida As New Hashtable

        Dim lPart(nlistaPartner.Count - 1) As List(Of RawData)

        For i = 0 To nlistaPartner.Count - 1
            lPart(i) = New List(Of RawData)
        Next

        For Each tmpRawData As RawData In listaReporter
            Dim indicePartner As Integer = TrovaIndice(tmpRawData.PARTNER_LAB, nlistaPartner)
            lPart(indicePartner).Add(tmpRawData)
        Next

        For i = 0 To nlistaPartner.Count - 1
            gida.Add(nlistaPartner(i), lPart(i))
        Next

        Return gida

    End Function

    Private Function CreaHashInvertito(ByVal RawDataPartner As List(Of RawData)) As Hashtable

        Dim gida As New Hashtable

        Dim lPart(nlistaPartnerInvertito.Count - 1) As List(Of RawData)

        For i = 0 To nlistaPartnerInvertito.Count - 1
            lPart(i) = New List(Of RawData)
        Next

        For Each tmpRawData As RawData In RawDataPartner
            Dim indicePartner As Integer = TrovaIndice(tmpRawData.REPORTER_LAB, nlistaPartnerInvertito)
            lPart(indicePartner).Add(tmpRawData)
        Next

        For i = 0 To nlistaPartnerInvertito.Count - 1
            gida.Add(nlistaPartnerInvertito(i), lPart(i))
        Next

        Return gida

    End Function

    Public Function CreaListaPartner(ByVal listaReporter As List(Of RawData))

        Dim bList As New List(Of String)

        Dim gPart = (From p In listaReporter Order By p.PARTNER_LAB Select p.PARTNER_LAB).Distinct
        bList = gPart.ToList()
        gPart = Nothing

        Return bList

    End Function

    Public Function CreaListaPartnerComeReporter(ByVal listaReporter As List(Of RawData))

        Dim bList As New List(Of String)

        Dim gPart = (From p In listaReporter Order By p.REPORTER_LAB Select p.REPORTER_LAB).Distinct
        bList = gPart.ToList()
        gPart = Nothing

        Return bList

    End Function

    Private Function estraiValoriMensili(ByVal Partner As String) As List(Of Indicatore)

        Dim lIndicatore As New List(Of Indicatore)

        Dim datiPartner As New List(Of RawData)
        datiPartner = nHashData(Partner)

        For indicemese = 1 To 12
            Dim indiceMeseStringa As String = ConvertiInteroInMese(indicemese)
            Dim partialValueMensile As Decimal = 0

            partialValueMensile = DammiValoreMeseRivedutoECorretto(nReporter, Partner,
                                            nFlux, nAnno.ToString, indiceMeseStringa, False,
                                            nReportType, datiPartner, nRawDataPartner, nAliasProduct)

            Dim indicatoreMese As New Indicatore
            indicatoreMese.Indice = indicemese
            indicatoreMese.Value = partialValueMensile

            lIndicatore.Add(indicatoreMese)
        Next

        Return lIndicatore

    End Function



#End Region


    Public Sub Agisci(ByVal listaReporter As List(Of RawData), ByVal listaPartner As List(Of RawData), ByVal _aliasProduct As String, ByVal kindReport As String, ByVal kFlux As String)

        nReportType = kindReport
        nAliasProduct = _aliasProduct
        nFlux = kFlux
        nRawDataPartner = listaPartner
        nRawDataReporter = listaReporter

        nlistaPartner = CreaListaPartner(listaReporter)
        nlistaPartnerInvertito = CreaListaPartnerComeReporter(listaPartner)
        nHashData = CreaHash(listaReporter)
        nHashDataInvertito = CreaHashInvertito(listaPartner)

        FaiLaCosaGiustaRiveduto(nlistaPartner)

    End Sub


    Private Sub FaiLaCosaGiustaRiveduto(ByVal kPartners As List(Of String))

        For Each tmpPartner As String In kPartners

            Dim TotaleAllYear As Decimal = 0
            Dim TotaleAllYearMediato As Decimal = 0


            Dim lIndi As New List(Of Indicatore)
            lIndi = estraiValoriMensili(tmpPartner)

            For Each tmpIndi As Indicatore In lIndi

                Dim indiceMeseStringa As String = ConvertiInteroInMese(tmpIndi.Indice)
                TotaleAllYear += tmpIndi.Value

                Dim partialValueMensileMediato As Decimal = 0

                partialValueMensileMediato = EstraiMedia(tmpIndi.Value, tmpPartner, nFlux, nAnno, indiceMeseStringa,
                                         nReportType, nRawDataPartner, nAliasProduct)

                TotaleAllYearMediato += partialValueMensileMediato

            Next

            If TotaleAllYear > 0 Then
                AggiungiSingoloTotaleATabella(False, tmpPartner, TotaleAllYear)
            End If

            If TotaleAllYearMediato > 0 Then
                AggiungiSingoloTotaleATabella(True, tmpPartner, TotaleAllYearMediato)
            End If

        Next

    End Sub

    Private Function DammiValoreMeseRivedutoECorretto(ByVal kReporter As String,
            ByVal Partner As String,
            ByVal kFlux As String,
            ByVal Anno As String,
            ByVal Mese As String,
            ByVal EseguiMediaBool As Boolean,
            ByVal kKindOfReport As String,
            ByRef ListaReporterAnnoScelto As List(Of RawData),
            ByRef ListaPartnerAnnoScelto As List(Of RawData),
            ByVal AliasProduct As String) As Decimal


        Dim var = SommaRawDataPerMonthReporterRivedutoECorretto(kReporter, Partner,
                                       kFlux, Anno, Mese, EseguiMediaBool,
                                       ListaReporterAnnoScelto, ListaPartnerAnnoScelto, AliasProduct)

        Dim partialValue As Decimal = 0
        If var IsNot Nothing Then
            Select Case kKindOfReport
                Case "Ton"
                    partialValue = var.Tonnellate
                Case "Euro"
                    partialValue = var.TotaleEuro
            End Select
        Else
            partialValue = 0
        End If

        Return partialValue

    End Function

    Private Function SommaRawDataPerMonthReporterRivedutoECorretto(ByVal Reporter As String, _
  ByVal Partner As String, _
  ByVal Flux As String, ByVal Year As String, _
  ByVal Month As String, _
  ByVal EseguiMediaBool As Boolean, _
  ByRef ListaReporterAnnoScelto As List(Of RawData),
  ByRef ListaPartnerAnnoScelto As List(Of RawData),
  ByVal AliasProduct As String) As RawData

        Try

            Dim ListaTemporanea As New List(Of RawData)
            Dim tonn As Decimal = 0
            Dim price As Decimal = 0
            Dim myFlux As String = String.Empty

            Dim FlussoNumerico As Integer = 0

            If Flux = "IMPORT" Then
                FlussoNumerico = 1
            ElseIf Flux = "EXPORT" Then
                FlussoNumerico = 2
            End If

            Dim myPeriod As String = ConvertiStringaMese(Month, Year)
            '        Dim nts As Integer = ConvertiStringaMeseHash(Month, nAnno)



            Dim tmpRawList As New List(Of RawData)
            tmpRawList = EstraiRawDataReporterRiveduto(myPeriod, ListaReporterAnnoScelto)


            If tmpRawList.Count <= 0 Then

                ' Devo invertire i ruoli

                If Flux = "IMPORT" Then
                    myFlux = "EXPORT"
                ElseIf Flux = "EXPORT" Then
                    myFlux = "IMPORT"
                Else
                    myFlux = String.Empty
                End If

                Dim lpa As New List(Of RawData)

                For Each tmpR As RawData In ListaPartnerAnnoScelto
                    If tmpR.REPORTER_LAB = Partner AndAlso tmpR.FLOW_LAB = myFlux Then
                        lpa.Add(tmpR)
                    End If
                Next

                tmpRawList = EstraiRawDataPartnerRiveduto(Partner, myPeriod, lpa)

            End If

            If tmpRawList.Count > 0 Then

                For Each tmpRaw As RawData In tmpRawList
                    If tmpRaw.INDICATORS_LAB = "QUANTITY_IN_100KG" Then
                        tonn += tmpRaw.INDICATOR_VALUE * 0.1
                    ElseIf tmpRaw.INDICATORS_LAB = "VALUE_IN_EUROS" Then
                        price += tmpRaw.INDICATOR_VALUE
                    End If

                Next

                Dim nuovoRawData As New RawData
                With nuovoRawData
                    .Tonnellate = tonn
                    If tonn <> 0 Then
                        .TotaleEuro = price / tonn
                    Else
                        .TotaleEuro = 0
                    End If

                    .FLOW = FlussoNumerico
                    .FLOW_LAB = Flux
                    .INDICATOR_VALUE = 0
                    .INDICATORS = 0
                    .INDICATORS_LAB = 0
                    .PARTNER_LAB = Partner
                    .PERIOD = 0
                    .PERIOD_LAB = myPeriod
                    .PRODUCT_LAB = ""
                    .REPORTER_LAB = Reporter

                    Dim tmpString As String
                    Dim tmpString2 As String

                    tmpString = tmpRawList(0).PERIOD
                    tmpString2 = Mid(tmpString, 1, 4)
                    .Year = CType(tmpString2, Integer)
                    .Month = Mid(tmpString, 5, 2)

                End With

                If EseguiMediaBool = True Then
                    Dim tmpList As New List(Of RawData)
                    tmpList.Add(nuovoRawData)
                    tmpList = CalcolaMediaRiveduto(tmpList, ListaPartnerAnnoScelto, AliasProduct)
                    Return tmpList(0)

                Else

                    Return nuovoRawData

                End If

            End If

        Catch ex As Exception
            Return Nothing
        End Try


    End Function

    Private Function ConvertiInteroInMese(ByVal indice As Integer) As String

        Select Case indice

            Case 1
                Return "Jan"
            Case 2
                Return "Feb"
            Case 3
                Return "Mar"
            Case 4
                Return "Apr"
            Case 5
                Return "May"
            Case 6
                Return "Jun"
            Case 7
                Return "Jul"
            Case 8
                Return "Aug"
            Case 9
                Return "Sep"
            Case 10
                Return "Oct"
            Case 11
                Return "Nov"
            Case 12
                Return "Dec"

        End Select

        Return String.Empty

    End Function

    Private Function EstraiRawDataReporterRiveduto(ByVal Period As Integer, ByVal ListaReporterAnnoScelto As List(Of RawData)) As List(Of RawData)

        Dim gPartner As New List(Of RawData)

        Try
            Dim varGigi = From p In ListaReporterAnnoScelto Where p.PERIOD = Period Select p
            gPartner = varGigi.ToList
            varGigi = Nothing
            Return gPartner
        Catch ex As Exception
            Return Nothing
        End Try

    End Function

    Private Function EstraiRawDataPartnerRiveduto(ByVal Reporter As String, _
         ByVal Period As Integer, _
         ByRef ListaPartnerAnnoScelto As List(Of RawData)) As List(Of RawData)


        Dim gPartner As New List(Of RawData)

        Try

            If Not ListaPartnerAnnoScelto Is Nothing Then

                Dim varGogo = From p In ListaPartnerAnnoScelto Where p.PERIOD = Period Select p
                gPartner = varGogo.ToList
                varGogo = Nothing

                Return gPartner
            Else

                Return Nothing

            End If

        Catch ex As Exception
            Return Nothing
        End Try

    End Function

    Private Function ConvertiStringaMese(ByVal InString As String, ByVal StringaAnno As String) As String

        Select Case InString
            Case "Jan"
                Return StringaAnno + "01"
            Case "Feb"
                Return StringaAnno + "02"
            Case "Mar"
                Return StringaAnno + "03"
            Case "Apr"
                Return StringaAnno + "04"
            Case "May"
                Return StringaAnno + "05"
            Case "Jun"
                Return StringaAnno + "06"
            Case "Jul"
                Return StringaAnno + "07"
            Case "Aug"
                Return StringaAnno + "08"
            Case "Sep"
                Return StringaAnno + "09"
            Case "Oct"
                Return StringaAnno + "10"
            Case "Nov"
                Return StringaAnno + "11"
            Case "Dec"
                Return StringaAnno + "12"
        End Select

        Return String.Empty

    End Function

    Private Function ConvertiStringaMeseHash(ByVal InString As String, ByVal StringaAnno As Integer) As Integer

        Select Case InString
            Case "Jan"
                Return StringaAnno * 100 + 1
            Case "Feb"
                Return StringaAnno * 100 + 2
            Case "Mar"
                Return StringaAnno * 100 + 3
            Case "Apr"
                Return StringaAnno * 100 + 4
            Case "May"
                Return StringaAnno * 100 + 5
            Case "Jun"
                Return StringaAnno * 100 + 6
            Case "Jul"
                Return StringaAnno * 100 + 7
            Case "Aug"
                Return StringaAnno * 100 + 8
            Case "Sep"
                Return StringaAnno * 100 + 9
            Case "Oct"
                Return StringaAnno * 100 + 10
            Case "Nov"
                Return StringaAnno * 100 + 11
            Case "Dec"
                Return StringaAnno * 100 + 12
        End Select

        Return String.Empty

    End Function

    Private Function CalcolaMediaRiveduto(ByVal inList As List(Of RawData),
                                  ByRef ListaPartnerAnnoScelto As List(Of RawData),
                                  ByVal AliasProduct As String) As List(Of RawData)

        Try

            For Each tmpRaw As RawData In inList

                Dim localList As New List(Of RawData)
                Dim tmpFlux As String
                Dim tonn As Decimal
                Dim price As Decimal

                If tmpRaw.FLOW_LAB = "EXPORT" Then
                    tmpFlux = "IMPORT"
                ElseIf tmpRaw.FLOW_LAB = "IMPORT" Then
                    tmpFlux = "EXPORT"
                Else
                    tmpFlux = String.Empty
                End If


                Dim lpa As New List(Of RawData)

                For Each tmpR As RawData In ListaPartnerAnnoScelto
                    If tmpR.REPORTER_LAB = tmpRaw.PARTNER_LAB AndAlso tmpR.FLOW_LAB = tmpFlux Then
                        lpa.Add(tmpR)
                    End If
                Next


                localList = EstraiRawDataPartnerRiveduto(tmpRaw.PARTNER_LAB, tmpRaw.PERIOD, lpa)

                For Each tmpList In localList

                    If tmpList.INDICATORS_LAB = "QUANTITY_IN_100KG" Then
                        tonn = tmpList.INDICATOR_VALUE * 0.1
                    ElseIf tmpList.INDICATORS_LAB = "VALUE_IN_EUROS" Then
                        price = tmpList.INDICATOR_VALUE
                    End If
                Next

                Dim nuoveTonn As Decimal
                Dim nuovoPrezzo As Decimal
                If tonn <> 0 Then
                    nuoveTonn = (tmpRaw.Tonnellate + tonn) / 2
                    nuovoPrezzo = (tmpRaw.TotaleEuro + (price / tonn)) / 2
                Else
                    nuoveTonn = tmpRaw.Tonnellate
                    nuovoPrezzo = tmpRaw.TotaleEuro
                End If

                tmpRaw.Tonnellate = System.Math.Round(nuoveTonn, 0)
                tmpRaw.TotaleEuro = System.Math.Round(nuovoPrezzo, 0)

            Next

            Return inList

        Catch ex As Exception

            Return inList

        End Try

    End Function

    Private Function EstraiMedia(ByVal OriginalValue As Decimal,
                    ByVal Partner As String,
                    ByVal kFlux As String,
                    ByVal Anno As String,
                    ByVal Mese As String,
                    ByVal kKindOfReport As String,
                    ByRef ListaPartnerAnnoScelto As List(Of RawData),
                    ByVal AliasProduct As String) As Decimal

        Dim localList As New List(Of RawData)

        Dim tonn As Decimal = 0
        Dim price As Decimal = 0
        Dim tmpFlux As String = String.Empty
        Dim Period As String = ConvertiStringaMese(Mese, Anno)

        If kFlux = "EXPORT" Then
            tmpFlux = "IMPORT"
        ElseIf kFlux = "IMPORT" Then
            tmpFlux = "EXPORT"
        End If


        Dim lpa As New List(Of RawData)
        Dim gda As New List(Of RawData)

        lpa = nHashDataInvertito(Partner)


        If Not lpa Is Nothing Then
            Dim kf = From p In lpa Where p.FLOW_LAB = tmpFlux Select p
            gda = kf.ToList

        End If

        localList = EstraiRawDataPartnerRiveduto(Partner, Period, gda)

        If Not localList Is Nothing AndAlso localList.Count > 0 Then

            For Each tmpList In localList

                If tmpList.INDICATORS_LAB = "QUANTITY_IN_100KG" Then
                    tonn += tmpList.INDICATOR_VALUE * 0.1
                ElseIf tmpList.INDICATORS_LAB = "VALUE_IN_EUROS" Then
                    price += tmpList.INDICATOR_VALUE
                End If
            Next

            If kKindOfReport = "Ton" Then

                Dim nuoveTonn As Decimal = 0
                nuoveTonn = (OriginalValue + tonn) / 2
                Return nuoveTonn
            ElseIf kKindOfReport = "Euro" Then

                Dim nuovoPrezzo As Decimal = 0

                If tonn <> 0 Then
                    nuovoPrezzo = (OriginalValue + (price / tonn)) / 2
                Else
                    nuovoPrezzo = OriginalValue
                End If

                Return nuovoPrezzo

            Else

                Return OriginalValue

            End If

        Else

            Return OriginalValue

        End If


    End Function

    Private Sub AggiungiSingoloTotaleATabella(ByVal isAveraged As Boolean,
                                      ByVal Partner As String,
                                      ByVal Total As Decimal)

        Dim mTotal As New Tabella_Totali
        mTotal.Reporter = nReporter
        mTotal.Averaged = isAveraged
        mTotal.Flow = nFlux
        mTotal.Indicator = nReportType
        mTotal.Partner = Partner
        mTotal.Product = nAliasProduct
        mTotal.Total = Total
        mTotal.Year = nAnno

        _db.Configuration.AutoDetectChangesEnabled = False
        _db.Tabella_Totali.Add(mTotal)
        _db.SaveChanges()



    End Sub
End Class
